#ifdef KITSCHY_DEBUG_MEMORY 
#include "debug_memorymanager.h"
#endif

#ifdef _WIN32
#include <windows.h>
#include <windowsx.h>
#else
#include <sys/time.h>
#include <time.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "SDL.h"
#include "SDL_ttf.h"
#include "BList.h"
#include "debug.h"
#include "keyboardstate.h"

#include "symbol.h"
#include "sort.h"
#include "ontology.h"
#include "featureterm.h"
#include "FTKBase.h"
#include "Ufeatureterm.h"
#include "AUfeatureterm.h"
#include "FT_refinement.h"
#include "FT_generalization.h"

#include "SpecialTerm.h"
#include "ST_floatInterval.h"

#include "eagerlazy.h"


/*						GLOBAL VARIABLES INITIALIZATION:							*/ 

char *application_name="Eager - Lazy knob";
int SCREEN_X=800;
int SCREEN_Y=600;
int COLOUR_DEPTH=32;
bool fullscreen=false;

/* Redrawing constant: */ 
const int REDRAWING_PERIOD=10;

/*						AUXILIAR FUNCTION DEFINITION:							*/ 


SDL_Surface *initialization(int flags) 
{
    const SDL_VideoInfo* info=0;
    int bpp=0;
	SDL_Surface *screen;

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Initializing SDL\n");
#endif

    if(SDL_Init(SDL_INIT_VIDEO)<0) {
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("Video initialization failed: %s\n",SDL_GetError());
#endif
		return 0;
    } /* if */ 

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("SDL initialized\n");
#endif

    info=SDL_GetVideoInfo();

    if(!info) {
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("Video query failed: %s\n",SDL_GetError());
#endif
		return 0;
    } /* if */ 

	if (fullscreen) {
		bpp=COLOUR_DEPTH;
	} else {
	    bpp=info->vfmt->BitsPerPixel;
	} /* if */ 

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Initializing video mode\n");
#endif

	screen=SDL_SetVideoMode(SCREEN_X,SCREEN_Y,bpp,flags);
    if(screen==0) {
#ifdef F1SPIRIT_DEBUG_MESSAGES
		output_debug_message("Video mode set failed: %s\n",SDL_GetError());
#endif
		return 0;
    } /* if */ 

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Video mode initialized\n");
#endif

	TTF_Init();
	
	SDL_WM_SetCaption(application_name, 0);
	SDL_ShowCursor(SDL_ENABLE);

	SDL_EnableUNICODE(1);

	return screen;
} /* initialization */ 


void finalization()
{
#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Finalizing SDL\n");
#endif

	TTF_Quit();
	SDL_Quit();

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("SDL finalized\n");
#endif

} /* finalization */ 



#ifdef _WIN32
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow)
#else
int main(int argc, char** argv)
#endif
{
	SDL_Surface *screen_sfc;
	KEYBOARDSTATE *k;
	EagerLazyApp *app;

	int time,act_time;
	SDL_Event event;
    bool quit = false;

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Application started\n");
#endif

	screen_sfc = initialization((fullscreen ? SDL_FULLSCREEN : 0));
	if (screen_sfc==0) return 0;

	k=new KEYBOARDSTATE();

	if (fullscreen) {
		screen_sfc = SDL_SetVideoMode(SCREEN_X, SCREEN_Y, COLOUR_DEPTH, (fullscreen ? SDL_FULLSCREEN : 0));
		SDL_WM_SetCaption(application_name, 0);
		SDL_ShowCursor(SDL_DISABLE);
	} /* if */ 

	app=new EagerLazyApp();

	time=SDL_GetTicks();

	while (!quit) {
		while( SDL_PollEvent( &event ) ) {
            switch( event.type ) {
                /* Keyboard event */
                case SDL_KEYDOWN:
					if (event.key.keysym.sym==SDLK_F12) {
						quit = true;
					} /* if */ 

					if (event.key.keysym.sym==SDLK_RETURN) {
						SDLMod modifiers;

						modifiers=SDL_GetModState();

						if ((modifiers&KMOD_ALT)!=0) {
							/* Toogle FULLSCREEN mode: */ 
							if (fullscreen) fullscreen=false;
									   else fullscreen=true;

							screen_sfc = SDL_SetVideoMode(SCREEN_X, SCREEN_Y, COLOUR_DEPTH, (fullscreen ? SDL_FULLSCREEN : 0));
							SDL_WM_SetCaption(application_name, 0);
							SDL_ShowCursor(SDL_ENABLE);
						} /* if */ 
					} /* if */ 

					/* Keyboard event */ 
					SDL_keysym *ks;
					ks=new SDL_keysym();
					*ks=event.key.keysym;
					k->keyevents.Add(ks);

                    break;

                /* SDL_QUIT event (window close) */
                case SDL_QUIT:
                    quit = true;
                    break;
            } /* switch */ 
        } /* while */ 


		act_time=SDL_GetTicks();
		if (act_time-time>=REDRAWING_PERIOD) {
			int max_frame_step=10;

			/* Cycle: */ 
			k->cycle();
			if (!app->cycle(k)) quit=true;
			k->keyevents.Delete();
		
			do {
				time+=REDRAWING_PERIOD;
				if ((act_time-time)>10*REDRAWING_PERIOD) time=act_time;
			
				app->draw(screen_sfc);
				SDL_Flip(screen_sfc);

				act_time=SDL_GetTicks();
				max_frame_step--;
			} while(act_time-time>=REDRAWING_PERIOD && max_frame_step>0);

		} /* if */ 

	} /* while */ 

	delete app;
	app=0;

	delete k;
	k=0;

	finalization();

#ifdef F1SPIRIT_DEBUG_MESSAGES
	output_debug_message("Application finished\n");
	close_debug_messages();
#endif

	return 0;
} /* main */ 
